package uts

import (
	"encoding/json"
	"fmt"
	"regexp"
	"strconv"
	"strings"
	"time"
)

// F64 转float64
func F64(str string) (f64 float64) {
	f64, _ = strconv.ParseFloat(str, 64)
	return
}

// F32 转float32
func F32(str string) (f32 float32) {
	return float32(F64(str))
}

// Now 返回当时日期，格式：2006-01-02 15:04:05
func Now() string {
	return time.Now().Format(`2006-01-02 15:04:05`)
}

// PrintJSON 对json数据进行格式化（带缩进），并打印
func PrintJSON(data any) (j string) {
	j = JSON(data)
	fmt.Println(j)
	return
}

// JSONStr 对json数据进行格式化（不带缩进）
func JSONStr(data any) string {
	b, _ := json.Marshal(data)
	return string(b)
}

// JSON 对json数据进行格式化（带缩进）
func JSON(data any) string {
	b, _ := json.MarshalIndent(data, "", "    ")
	return string(b)
}

// IIf 三元：当条件为true时，返回ifTrue，否则返回ifFalse
func IIf[T any](condition bool, ifTrue, ifFalse T) T {
	if condition {
		return ifTrue
	} else {
		return ifFalse
	}
}

// Space 返回指定数量的空格
func Space(n int) string {
	return strings.Join(make([]string, n+1), " ")
}

// NewErr 生成 error ，多个str以"："分隔
func NewErr(strs ...any) error {
	return fmt.Errorf(ArrJoin(strs, "："))
}

// Str 转为string
func Str(v any) string {
	str := fmt.Sprintf("%+v", v)
	return IIf(str == "<nil>", "", str)
}

// Nvl 返回参数中第1个不为空的值
//   - 类似oracle的nvl
func Nvl[T comparable](val T, vals ...T) T {
	var empty T
	if val != empty {
		return val
	}
	for _, s := range vals {
		if s != empty {
			return s
		}
	}
	return val
}

// Trim 清除字符串首尾的指定内容
//   - 默认cutest `[\s\t\r\n]+`
func Trim(str string, cutset ...string) string {
	if len(cutset) == 0 {
		cutset = []string{`[\s\t\r\n]+`}
	}

	for _, s := range cutset {
		r := regexp.MustCompile(fmt.Sprintf(`(^%s)|(%s$)`, s, s))
		str = r.ReplaceAllString(str, "")
	}
	return str
}

// Decode 类似oracle的decode、php8的match
//   - 参数为两个一组，依次往后匹配
//   - 1. 若某组的首个值与val相等，则返回该组第2个值
//   - 2. 若某组仅1个值，则直接返回该值
//   - 3. 否则返回与val相同类型的空值
func Decode[T comparable](val T, matches ...T) (v T) {
	var res T
	for i, l := 0, len(matches); i < l; i += 2 {
		if i == l-1 {
			return matches[i]
		} else if matches[i] == val {
			return matches[i+1]
		}
	}
	return res
}
